package com.example.springbootdemo.sevice;

import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.example.springbootdemo.dto.SmsDTO;
import com.example.springbootdemo.dto.UserExcelDTO;
import com.example.springbootdemo.entity.User;
import com.example.springbootdemo.enums.GenderEnum;
import com.example.springbootdemo.event.SmsEvent;
import com.example.springbootdemo.listener.UserExcelListener;
import com.example.springbootdemo.mybatisplus.IUserService;
import com.example.springbootdemo.util.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  用户业务接口
 * </p>
 *
 * @author yurenwei
 * @since 2023/9/7
 */
@Slf4j
@Service
public class UserService {

    @Autowired
    private IUserService iUserService;
    @Autowired
    private ApplicationContext applicationContext;


    /**
     * 添加用户
     *
     * @param params 新增参数
     */
    @CachePut(value = "userCache",key = "#params.id")
    public User add(User params){
        params.setId(IdUtil.getSnowflakeNextId());
        // 保存用户
        iUserService.save(params);
        log.info("保存用户成功！");

        SmsDTO sms = new SmsDTO()
                .setUserName(params.getUserName())
                .setPhone(params.getPhone())
                .setMsg("恭喜您注册成功！");
        // 调用短信事件发送短信
        applicationContext.publishEvent(new SmsEvent(this,"短信通知事件",sms));
        log.info("保存用户结束！");

        return params;
    }

    /**
     * 修改用户
     *
     * @param params 修改参数
     */
    @CachePut(value = "userCache",key = "#params.id")
    public User update(User params) {
        User user = iUserService.getById(params.getId());
        BeanUtils.copyProperties(params,user);
        iUserService.updateById(user);

        return user;
    }

    /**
     * 查询详情
     *
     * @param id 用户id
     * @return User
     */
    @Cacheable(value = "userCache",key = "#id")
    public User queryDetails(Long id) {
        return iUserService.getById(id);
    }

    /**
     * 删除用户
     *
     * @param id 用户id
     */
    @CacheEvict(value = "userCache",key = "#id")
    public void delete(Long id) {
        iUserService.removeById(id);
    }

    /**
     * 查询所有用户
     *
     * @return List<User>
     */
    public List<User> getAll() {
        return iUserService.list();
    }

    /**
     * 导入excel
     *
     * @param file excel文件
     */
    public void importUser(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(), UserExcelDTO.class, new UserExcelListener(iUserService))
                    .sheet(0)
                    .headRowNumber(1)
                    .doRead();
        } catch (IOException e) {
            log.error("导入用户数据异常：{}",e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 导出
     *
     * @param response 响应
     */
    public void export(HttpServletResponse response) {
        // 查询所有用户
        List<User> list = iUserService.list();
        // 转换数据
        List<UserExcelDTO> excelList = list.stream().map(item ->
                {
                    UserExcelDTO user = new UserExcelDTO();
                    user.setUserName(item.getUserName());
                    user.setPhone(item.getPhone());
                    user.setGender(GenderEnum.MALE.equals(item.getGender())?"男":"女");
                    user.setAddress(item.getAddress());
                    user.setStatus(item.getStatus()?"启用":"禁用");
                    user.setRegisterTime(item.getRegisterTime());

                    return user;
                })
                .collect(Collectors.toList());
        // 调用工具类导出
        ExcelUtil.exportExcel("用户数据","用户",excelList,UserExcelDTO.class,response);
    }

}
